package com.msk.web.controller.wlhy;

import com.google.common.collect.Maps;
import com.msk.common.core.controller.BaseController;
import com.msk.common.core.domain.R;
import com.msk.common.core.domain.model.LoginUser;
import com.msk.common.exception.GlobalException;
import com.msk.common.utils.StringUtils;
import com.msk.framework.web.utils.TokenUtils;
import com.msk.sys.domain.Dict;
import com.msk.sys.domain.User;
import com.msk.sys.service.DictService;
import com.msk.sys.service.SystemService;
import com.msk.sys.utils.DictMskUtils;
import com.msk.wlhy.domain.*;
import com.msk.wlhy.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author llh
 * @date 2023/5/9
 * @description 司机我的运单接口
 */
@Api(tags = "司机我的运单接口")
@RestController
@RequestMapping("/api/driverWayBill")
public class DriverWayBillController extends BaseController {

    @Autowired
    private HtDriverFileService htDriverFileService;

    @Autowired
    private HtTransportDetailService htTransportDetailService;

    @Autowired
    private HtTransportListService htTransportListService;

    @Autowired
    private SystemService systemService;

    @Autowired
    private InformationService informationService;

    @Autowired
    private HtCarFilesService htCarFilesService;

    @Autowired
    private DictService dictService;

    /**
     * @author llh
     * @date 2023/5/9
     * @return com.msk.common.core.domain.R<?>
     * @description 运单数量信息接口
     */
    @ApiOperation("运单数量信息接口")
    @PostMapping("/complateOrderCount")
    public R<?> complateOrderCount(@RequestBody Map<String, String> map) {
        HtDriverFile htDriverFile = TokenUtils.getDriverLogin();
        HtTransportDetail htTransportDetail = new HtTransportDetail();
        String dateStatus = String.valueOf(map.get("dateStatus"));
        String startDate = null;
        String endDate = null;
        if (dateStatus != null && "3".equals(dateStatus)) {
            startDate = String.valueOf(map.get("startDate"));
            endDate = String.valueOf(map.get("endDate"));
            endDate += " 23:59:59";
        }
        if (htDriverFile != null) {
            htTransportDetail.setUserId(htDriverFile.getUserId());
            htTransportDetail.setDriverId(htDriverFile.getId());
            htTransportDetail = htTransportDetailService.findComplateDetailCount(htTransportDetail, dateStatus, startDate, endDate);
        } else {
            htTransportDetail.setAttstr04("0");
            htTransportDetail.setAttstr05("0");
        }
        return R.appOk(htTransportDetail);
    }

    /**
     * @author llh
     * @date 2023/5/9
     * @return com.msk.common.core.domain.R<?>
     * @description 运单列表接口
     */
    @ApiOperation("运单列表接口")
    @PostMapping("/allOrderList")
    public R<?> complateOrderListData(@RequestBody Map<String, String> map) {
        HtDriverFile htDriverFile = TokenUtils.getDriverLogin();
        if (htDriverFile == null) {
            return R.appFail(400101, "用户未认证");
        }
        HtTransportDetail htTransportDetail = new HtTransportDetail();
        htTransportDetail.setDriverId(htDriverFile.getId());
        String status = map.get("status");
        if (StringUtils.isNotBlank(status)) {
            htTransportDetail.setStatus(status);
        }
        htTransportDetail.getParams().put("pageNum", map.get("pageNum"));
        htTransportDetail.getParams().put("pageSize", map.get("pageSize"));
        htTransportDetail.getParams().put("orderByStr", "a.create_date desc");
        startPageJson(htTransportDetail.getParams(), "");
        List<Map<String, Object>> list = htTransportDetailService.findComplateDetailList(htTransportDetail);
        List<Dict> insuranceCodeDictList = DictMskUtils.getDictListNew("insurance_code");
        List<Dict> priceWayDictList = DictMskUtils.getDictListNew("price_way");
        String isOverload = dictService.findByTypeAndLabel("is_overload", "overload_setting"); //是否允许超载
        for (Map<String, Object> result : list) {
            String isEnter = String.valueOf(result.get("isEnter"));
            String insuranceCompanyCode = String.valueOf(result.get("insuranceCompanyCode"));
            String priceWay = String.valueOf(result.get("priceWay"));
            if ("1".equals(result.get("status")) && ("0".equals(isEnter) || "2".equals(isEnter))) {
                result.put("status", "5");
            }
            if ("3".equals(result.get("status")) && "1".equals(result.get("isBilling"))) {
                result.put("status", "4");
            }
            if (StringUtils.isNotEmpty(insuranceCompanyCode) && StringUtils.isNotEmpty(insuranceCodeDictList)) {
                result.put("insuranceCompanyName", DictMskUtils.getDictLabelNew(insuranceCompanyCode, insuranceCodeDictList, ""));
            }
            if (StringUtils.isNotEmpty(priceWay) && StringUtils.isNotEmpty(priceWayDictList)) {
                result.put("priceWayAlias", DictMskUtils.getDictLabelNew(priceWay, priceWayDictList, ""));
            }
            result.put("isOverload", isOverload);
        }
        return R.appOk(getDataTable(list));
    }

    /**
     * @author llh
     * @date 2023/5/16
     * @return com.msk.common.core.domain.R<?>
     * @description 取消运单接口
     */
    @ApiOperation("取消运单接口")
    @PostMapping("/cancelWaybill")
    public R<?> cancelWaybill(@RequestBody Map<String, String> map) {
        Map<String, String> result = new HashMap<String, String>();
        try {
            String policyNumber = map.get("policyNumber");
            String insuranceCompanyCode = map.get("insuranceCompanyCode");
            HtTransportDetail htTransportDetail = htTransportDetailService.get(map.get("id"));
            if (htTransportDetail.getGoodsWeight() == null) {
                htTransportDetail.setGoodsWeight(Double.valueOf(0));
            }
            htTransportDetail.setRemarks(map.get("remarks"));
            if ("1".equalsIgnoreCase(htTransportDetail.getAuditStatus())) {
                result.put("flag", "fail");
                String message = "删除保单失败，保单已审核通过";
                result.put("message", message);
                return R.appOk(result);
            }
            boolean flag = htTransportDetailService.delArrival(htTransportDetail);
            HtDriverFile driverLogin = TokenUtils.getDriverLogin();
            driverLogin.setDriverStatus("0");//闲置
            htDriverFileService.updatedriverStatus(driverLogin);
            if (flag) {
                result.put("flag", "success");
            } else {
                String message = "删除保单失败，请联系系统管理员";
                result.put("message", message);
            }
        } catch (Exception e) {
            result.put("flag", "fail");
            String message = "删除保单失败，请联系系统管理员";
            if (e instanceof GlobalException) {
                message = e.getMessage();
            }
            result.put("message", message);
            e.printStackTrace();
        }
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/5/23
     * @return com.msk.common.core.domain.R<?>
     * @description 查看运单详细信息
     */
    @ApiOperation("查看运单详细信息")
    @PostMapping("/showWayBillDetails")
    public R<?> showWayBillDetails(@RequestBody HtTransportDetail htTransportDetail) {
        HtDriverFile htDriverFile = TokenUtils.getDriverLogin();
        htTransportDetail.setDriverId(htDriverFile.getId());
        HtTransportDetail result = htTransportDetailService.selectDetailsById(htTransportDetail);
        String isOverload = dictService.findByTypeAndLabel("is_overload", "overload_setting"); //是否允许超载
        result.setIsOverload(isOverload);
        String isEnter = result.getHtTransportList().getIsEnter();
        if ("3".equals(result.getStatus()) && "1".equals(result.getIsBilling())) {
            result.setStatus("4");
        }
        if ("1".equals(result.getStatus()) && ("0".equals(isEnter) || "2".equals(isEnter))) {
            result.setStatus("5");
        }
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/5/24
     * @return com.msk.common.core.domain.R<?>
     * @description 运单录入接口
     */
    @ApiOperation("运单录入接口")
    @PostMapping("/entryWayBill")
    public R<?> entryWayBill(@RequestBody HtTransportList htTransportList) {
        Map<String, Object> result = Maps.newHashMap();
        try {
            //参数校验
            String message = validateModel(htTransportList);
            if (StringUtils.isNotBlank(message)) {
                result.put("flag", false);
                result.put("message", message);
                return R.appOk(result);
            }
            //设置允许超载比例
            HtCarFiles htCarFiles = htCarFilesService.findCarFilesByDriverId(htTransportList.getAttstr01());
            Double goodsWeight = htTransportList.getHtTransportDetail().getGoodsWeight();
            String isOverload = dictService.findByTypeAndLabel("is_overload", "overload_setting");
            if("1".equals(isOverload)){
                String overloadProportion = dictService.findByTypeAndLabel("overload_proportion", "overload_setting");
                BigDecimal allowableWeight = new BigDecimal(htCarFiles.getCarLoad() * (1 + (Double.parseDouble(overloadProportion))/100)).setScale(3, RoundingMode.HALF_DOWN);
                if(goodsWeight > allowableWeight.doubleValue()){
                    result.put("flag", false);
                    result.put("message", "接单重量不能超过车辆核载重量");
                    return R.appOk(result);
                }
            }else{
                if(goodsWeight > htCarFiles.getCarLoad()){
                    result.put("flag", false);
                    result.put("message", "接单重量不能超过车辆核载重量");
                    return R.appOk(result);
                }
            }
            //status:2(已装货)
            if (htTransportList.getStatus().equals("2") && htTransportList.getDispatchTime() == null) { //已派车 记录派车时间
                htTransportList.setDispatchTime(new Date());
            }
            if (!StringUtils.isNotBlank(htTransportList.getIsOrders())) {
                htTransportList.setIsOrders("0"); //未接单状态
            }
            htTransportList.setCreateBy(new User(TokenUtils.getMpLoginUser().getLoginId()));
            if (htTransportList.getHtTransportDetail().getGoodsWeight() <=0){
                result.put("flag", false);
                result.put("message", "请输入有效重量");
                return R.appOk(result);
            }
            htTransportListService.saveDataNew(htTransportList);
            if ("1".equals(TokenUtils.getMpLoginUser().getLoginObject())) {
                HtDriverFile driverLogin = TokenUtils.getDriverLogin();
                driverLogin.setDriverStatus("1");//待运
                htDriverFileService.updatedriverStatus(driverLogin);
            }
            result.put("flag", true);
            result.put("message", "运单录入成功");
        } catch (Exception e) {
            result.put("flag", false);
            result.put("message", e.toString());
        }
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/5/24
     * @return com.msk.common.core.domain.R<?>
     * @description 获取字典列表接口
     */
    @ApiOperation("获取字典列表接口")
    @PostMapping("/getDictList")
    public R<?> getDictList(@RequestBody Map<String, String> map) {
        String type = map.get("type");
        List<Dict> dictList = DictMskUtils.getDictList(type);
        return R.appOk(getDataTable(dictList));
    }

    /**
     * @author llh
     * @date 2023/5/24
     * @return com.msk.common.core.domain.R<?>
     * @description 上传保单接口
     */
    @ApiOperation("上传保单接口")
    @PostMapping("/uploadInsuranceFile")
    public R<?> uploadInsuranceFile(@RequestBody HtTransportDetail htTransportDetail) {
        Map<String, Object> result = Maps.newHashMap();
        try {
            String auditStatus = htTransportDetail.getAuditStatus();
            if (StringUtils.isNotBlank(auditStatus) && !"1".equals(auditStatus))
                htTransportDetail.setAuditStatus("0"); //0：待审核

            htTransportDetailService.uploadInsuranceFile(htTransportDetail);
            result.put("flag", true);
            result.put("message", "上传成功");
        } catch (Exception e) {
            result.put("flag", false);
            result.put("message", e.toString());
        }
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/5/24
     * @return com.msk.common.core.domain.R<?>
     * @description 上传发货单或收货单接口
     */
    @ApiOperation("上传发货单或收货单接口")
    @PostMapping("/uploadInvoiceOrReceipt")
    public R<?> uploadInvoiceOrReceipt(@RequestBody HtTransportDetail htTransportDetail) {
        Map<String, Object> result = Maps.newHashMap();
        try {
            LoginUser loginUser = TokenUtils.getMpLoginUser();
            String invoicePic = htTransportDetail.getAttstr02(); //发货单
            String receiptPic = htTransportDetail.getAttstr01(); //收货单
            Date startDate = htTransportDetail.getStartDate(); //发货日期
            if(StringUtils.isNotEmpty(receiptPic) && startDate != null){
                Date nowDate = new Date();
                if(!((nowDate.getTime() - startDate.getTime()) >= 1200000)){
                    result.put("flag", false);
                    result.put("message", "到达时间必须在发货时间之后,且时间必须间隔20分钟以上");
                    return R.appOk(result);
                }
            }
            HtDriverFile driverLogin = TokenUtils.getDriverLogin();
            HtDriverFile driver = new HtDriverFile();
            Map<String, Object> map;
            if (StringUtils.isNotBlank(invoicePic)) {
                if ("1".equals(loginUser.getLoginObject())) {
                    driverLogin.setDriverStatus("2");//在途
                    htDriverFileService.updatedriverStatus(driverLogin);
                } else if ("3".equals(loginUser.getLoginObject())) {
                    map = htTransportDetailService.selectHtTransportDetail(htTransportDetail);
                    String id = StringUtils.getString(map.get("attstr03"));
                    driver.setId(id);
                    driver.setDriverStatus("2");//在途
                    htDriverFileService.updatedriverStatus(driver);
                }
                htTransportDetail.setStatus("2"); //2：已发运 3：已签收
            }
            if (StringUtils.isNotBlank(receiptPic)) {
                if ("1".equals(loginUser.getLoginObject())) {
                    driverLogin.setDriverStatus("0");//闲置
                    htDriverFileService.updatedriverStatus(driverLogin);
                } else if ("3".equals(loginUser.getLoginObject())) {
                    map = htTransportDetailService.selectHtTransportDetail(htTransportDetail);
                    String id = StringUtils.getString(map.get("attstr03"));
                    driver.setId(id);
                    driver.setDriverStatus("0");//在途
                    htDriverFileService.updatedriverStatus(driver);
                }
                htTransportDetail.setStatus("3");
            }
            htTransportDetailService.uploadInvoiceOrReceipt(htTransportDetail);
            result.put("flag", true);
            result.put("message", "上传成功");
        } catch (Exception e) {
            result.put("flag", false);
            result.put("message", e.toString());
        }
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/6/7
     * @return com.msk.common.core.domain.R<?>
     * @description 司机提醒付款接口
     */
    @ApiOperation("司机提醒付款接口")
    @PostMapping("/reminderPayment")
    public R<?> reminderPayment(@RequestBody Map<String, String> params) {
        HtDriverFile htDriverFile = TokenUtils.getDriverLogin();
        String code = params.get("code");
        String title = "司机请款申请";
        boolean flag = false;
        //限制重复发送消息
        Information info = new Information();
        User user = systemService.getUser("dddc3d5969014e298cb455e8f862eefd");
        info.setApplyCode(code);
        info.setUser(user);
        List<Information> infoList = informationService.findList(info);
        for (Information res : infoList) {
            if (title.equals(res.getTitle()) && res.getDetails().contains(htDriverFile.getName()) && res.getApplyCode().equals(code)) {
                flag = false;
                return R.appOk(flag, "重复发送提醒");
            }
        }
        //消息提醒
        Information information = new Information();
        information.setUser(user);
        //消息标题
        information.setTitle(title);
        information.setDetails("司机【" + htDriverFile.getName() + "】货源已签收，请尽快为该司机支付货款");
        //查看状态
        information.setState("0");
        information.setApplyCode(code);
        information.setAuditDate(new Date());
        informationService.save(information);
        flag = true;
        return R.appOk(flag);
    }

    /**
     * @author llh
     * @date 2023/7/4
     * @return com.msk.common.core.domain.R<?>
     * @description 获取运单起始位置信息
     */
    @ApiOperation("获取运单起始位置信息")
    @PostMapping("/getCoordinateInfo")
    public R<?> getCoordinateInfo(@RequestBody Map<String, String> params) {
        String shippingNoteNumber = params.get("shippingNoteNumber");
        if (StringUtils.isEmpty(shippingNoteNumber)) {
            return R.appFail(2001, "参数运单号#shippingNoteNumber为空");
        }
        Map<String, Object> result = htTransportDetailService.getLngAndLatInfo(shippingNoteNumber);
        return R.appOk(result);
    }

    /**
     * @author llh
     * @date 2023/7/13
     * @return com.msk.common.core.domain.R<?>
     * @description SDK行程信息变更
     */
    @ApiOperation("SDK行程信息变更")
    @PostMapping("/changeItinerary")
    public R<?> changeItinerary(@RequestBody HtTransportDetail htTransportDetail){
        if(htTransportDetailService.get(htTransportDetail.getId()).getSdkEndTrip() == 1){
            return R.appFail(400101,"重复进行结束行程信息变更");
        }
        Map<String,Object> result = new HashMap<>();
        int count = htTransportDetailService.updateItinerary(htTransportDetail);
        if(count > 0){
            result.put("flag",true);
            result.put("message","更新行程信息成功");
        }else{
            result.put("flag",false);
            result.put("message","更新行程信息失败");
        }
        return R.appOk(result);
    }
}
